#include "ALEDoG.h"

CALEDoG::CALEDoG()
{
}

CALEDoG::CALEDoG(CALStepItem* pStepItem)
{
	m_pStepItem = pStepItem;
}

CALEDoG::~CALEDoG()
{
}

void CALEDoG::test()
{
	//if (m_strFileName.empty()) return;

	//Mat img = imread(m_strFileName, 0);
	//Mat A, B, C, a;
	//int threshold = 3;
	//A = Process(img, 0.3, 0.4, Size(5, 5));
	//B = Process(img, 0.6, 0.7, Size(5, 5));
	//C = Process(img, 0.7, 0.8, Size(5, 5));
	//a = getExtrema(A, B, C, threshold);
	////const char* filename = "output.txt";
	////writeMatToFile(B, filename);
	//Mat imgB = imread(m_strFileName);
	//drawExtrema(imgB, a);
}

void CALEDoG::convert()
{
	if (m_pStepItem == NULL) return;

	try
	{
		CALSIEDoG* pStepItem = (CALSIEDoG*)m_pStepItem;

		int nThreshold = pStepItem->GetItemThreshold();
		Mat gray;
		cvtColor(m_srcMat, gray, CV_RGB2GRAY);
		//Mat img = imread(m_strFileName, 0);
		Mat A, B, C, a;
		//int threshold = 3;
		A = Process(gray, 0.3, 0.4, Size(5, 5));
		B = Process(gray, 0.6, 0.7, Size(5, 5));
		C = Process(gray, 0.7, 0.8, Size(5, 5));
		a = getExtrema(A, B, C, nThreshold);
		//const char* filename = "output.txt";
		//writeMatToFile(B, filename);
		//Mat imgB = imread(m_strFileName);
		m_dstMat = drawExtrema(m_srcMat, a);

		SetDstType(AL_DST_Mat_One);
	}
	catch (...)
	{

	}
}

void CALEDoG::convert(const Mat &src, Mat &dst)
{

}

Mat CALEDoG::Process(Mat &A, double sig1, double sig2, Size Ksize)
{
	Mat AF, out, out1, out2;
	A.convertTo(AF, CV_32FC1);
	GaussianBlur(AF, out1, Ksize, sig1, 0);
	GaussianBlur(AF, out2, Ksize, sig2, 0);
	subtract(out1, out2, out);
	return out;
}

Mat CALEDoG::getExtrema(Mat &A, Mat &B, Mat &C, int thresh)
{
	Mat block;
	Mat extr = Mat::zeros(A.rows, A.cols, CV_32FC1);
	double minv, maxv;
	Point minLoc, maxLoc;
	for (int i = 1; i < A.rows - 2; i++)
	{
		for (int j = 1; j < A.cols - 2; j++)
		{
			block.release();
			block.push_back(A(Range(i - 1, i + 2), Range(j - 1, j + 2)));
			block.push_back(B(Range(i - 1, i + 2), Range(j - 1, j + 2)));
			block.push_back(C(Range(i - 1, i + 2), Range(j - 1, j + 2)));
			minMaxLoc(block, &minv, &maxv, &minLoc, &maxLoc);
			if ((maxLoc.x == 1 && maxLoc.y == 4) && maxv >(double)thresh)
				extr.at<float>(i, j) = 1;
			if ((minLoc.x == 1 && minLoc.y == 4) && minv < (double)(-thresh))
				extr.at<float>(i, j) = -1;
		}
	}
	return extr;
}

Mat CALEDoG::drawExtrema(Mat img, Mat &extr)
{
	Point center;
	int r = 2;
	for (int i = 0; i < img.rows; i++)
	{
		for (int j = 0; j < img.cols; j++)
		{
			if (extr.at<float>(i, j) == -1)
			{
				center = Point(j, i);
				circle(img, center, r, Scalar(0, 255, 0));
			}
			if (extr.at<float>(i, j) == 1)
			{
				center = Point(j, i);
				circle(img, center, r, Scalar(0, 0, 255));
			}
		}
	}

	//namedWindow("DoG");
	//imshow("DoG", img);
	return img;
}